﻿' Copyright (c) Microsoft Corporation.  All rights reserved.

Imports MyTravelPostService.MyTravelPostModel

Public Class MyTravelPostService
    Implements IMyTravelPostService

    Public Function GetAllTravelBlogs() As List(Of Blog) Implements IMyTravelPostService.GetAllTravelBlogs
        Try
            ' the creation of the travelEntities opens the connection 
            ' and sets up all the metadata information automatically for you.
            Using mytravelentities As New MyTravelEntities

                ' set the blogs merge option to no tracking since this is a
                ' service that doesn't need to have change tracking.
                mytravelentities.Blogs.MergeOption = MergeOption.NoTracking

                ' we need to get the blogs from the travel posts from the blogs
                ' that have postings
                Dim travelBlogs = From b In mytravelentities.Blogs.Include("Person") _
                                  Where b.BlogPosts.Count > 0 _
                                  Select b

                Return travelBlogs.ToList()
            End Using
        Catch ex As Exception
            ' NOTE: You should do your own exception handling here
            ' problems may be connection, metadata, or there problems.
            Throw ex
        End Try

    End Function

    ' see IMyTravelPostService for details.
    Public Function GetBlog(ByVal blogID As Integer) As Blog Implements IMyTravelPostService.GetBlog
        Try
            ' the creation of the travelEntities opens the connection 
            ' and sets up all the metadata information automatically for you.
            Using mytravelentities As New MyTravelEntities
                ' set the blogs merge option to no tracking since this is a
                ' service that doesn't need to have change tracking.
                mytravelentities.Blogs.MergeOption = MergeOption.NoTracking

                ' query for a specific blog posting
                Dim blog = (From b In mytravelentities.Blogs.Include("Person") _
                               Where b.BlogID = blogID _
                               Select b).First()

                ' return the first one.
                Return blog
            End Using
        Catch ex As Exception
            ' NOTE: You should do your own exception handling here
            ' problems may be connection, metadata, or there problems.
            Throw ex
        End Try
    End Function

    ' see IMyTravelPostService for details.
    Public Function GetLatestBlogPosting(ByVal requestedBlog As Blog) As BlogPost Implements IMyTravelPostService.GetLatestBlogPosting
        Try
            ' the creation of the travelEntities opens the connection 
            ' and sets up all the metadata information automatically for you.
            Using mytravelentities As New MyTravelEntities
                ' set the blogs merge option to no tracking since this is a
                ' service that doesn't need to have change tracking.
                mytravelentities.BlogPosts.MergeOption = MergeOption.NoTracking

                ' get the latest blog post, with the comments and the people
                ' I'm querying for all the blog posts that are related to this blog.
                ' I want to include the comments and the people that wrote the comments.
                ' I also want only the most recent posting.
                ' Note: Since we use the EntityKey that is put on the EntityReference
                ' we can either do a tracking query or use span.
                Dim latestPost = (From bp In mytravelentities.BlogPosts.Include("Comments.Person").Include("Blog") _
                                     Where bp.Blog.BlogID = requestedBlog.BlogID _
                                     Order By bp.BlogDate Descending _
                                     Select bp).First()
                Return latestPost
            End Using
        Catch ex As Exception
            ' NOTE: You should do your own exception handling here
            ' problems may be connection, metadata, or there problems.
            Throw ex
        End Try
    End Function

    ' see IMyTravelPostService for details.
    Public Function GetPeople() As List(Of Person) Implements IMyTravelPostService.GetPeople
        Try
            ' the creation of the travelEntities opens the connection 
            ' and sets up all the metadata information automatically for you.
            Using mytravelentities As New MyTravelEntities
                ' set the blogs merge option to no tracking since this is a
                ' service that doesn't need to have change tracking.
                mytravelentities.People.MergeOption = MergeOption.NoTracking
                Return mytravelentities.People.ToList()
            End Using
        Catch ex As Exception
            ' NOTE: You should do your own exception handling here
            ' problems may be connection, metadata, or there problems.
            Throw ex
        End Try
    End Function

    ' see IMyTravelPostService for details.
    Public Function AddComment(ByVal newComment As Comment) As Comment Implements IMyTravelPostService.AddComment
        Try
            ' the creation of the travelEntities opens the connection 
            ' and sets up all the metadata information automatically for you.
            Using mytravelentities As New MyTravelEntities

                ' add the comment, since the comment carries the dependent ends as 
                ' EntityReferences, this is all that is need to update the database.
                mytravelentities.AddToComments(newComment)

                Try
                    ' once you have the reference, the properties are changed
                    ' tracked so modifications are update during SaveChanges
                    mytravelentities.SaveChanges()
                Catch opt As OptimisticConcurrencyException
                    ' catching this exception allows you to 
                    ' refresh MyTravelPostEntities with either store/client wins
                    ' project the MyTravelPostEntities into this failed MyTravelPostEntities.
                    Dim failedEntities = From e3 In opt.StateEntries Select e3.Entity

                    ' Note: in future you should be able to just pass the opt.StateEntities in to refresh.
                    mytravelentities.Refresh(RefreshMode.ClientWins, failedEntities.ToList())
                    mytravelentities.SaveChanges()
                End Try
            End Using
        Catch ex As Exception
            ' NOTE: You should do your own exception handling here
            ' problems may be connection, metadata, or there problems.
            Throw ex
        End Try

        ' return the updated comment to the user with the new entity key
        Return newComment
    End Function
    ' see IMyTravelPostService for details.
    Public Sub DeleteComment(ByVal deleteComment As Comment) Implements IMyTravelPostService.DeleteComment
        Try
            ' the creation of the travelEntities opens the connection 
            ' and sets up all the metadata information automatically for you.
            Using mytravelentities As New MyTravelEntities

                ' attach the comment and delete.
                mytravelentities.Attach(deleteComment)

                ' call delete on the object
                mytravelentities.DeleteObject(deleteComment)
                
                Try
                    ' call save changes to commit the deleted comments.
                    mytravelentities.SaveChanges()
                Catch opt As OptimisticConcurrencyException
                    ' catching this exception allows you to 
                    ' refresh MyTravelPostEntities with either store/client wins
                    ' project the MyTravelPostEntities into this failed MyTravelPostEntities.
                    Dim failedEntities = From e3 In opt.StateEntries Select e3.Entity

                    ' Note: in future you should be able to just pass the opt.StateEntities in to refresh.
                    mytravelentities.Refresh(RefreshMode.ClientWins, failedEntities.ToList())
                    mytravelentities.SaveChanges()
                End Try

            End Using
        Catch ex As Exception
            ' NOTE: You should do your own exception handling here
            ' problems may be connection, metadata, or there problems.
            Throw ex
        End Try
    End Sub

    ' see IMyTravelPostService for details.
    Public Function UpdateComments(ByVal orginalComments As List(Of Comment), ByVal updatedComments As List(Of Comment)) As List(Of Comment) Implements IMyTravelPostService.UpdateComments
        Try
            ' the creation of the travelEntities opens the connection 
            ' and sets up all the metadata information automatically for you.
            Using mytravelentities As New MyTravelEntities
                ' loop through all the orginal comments and attach
                For Each originalComment In orginalComments
                    mytravelentities.Attach(originalComment)
                Next

                ' new loop through the updated comments calling ApplyPropertyChanges
                ' ApplyPropertyChanges finds the existing tracked entity and updates
                ' the properties.
                For Each updatedComment In updatedComments
                    mytravelentities.ApplyPropertyChanges("Comments", updatedComment)
                Next

                Try
                    ' save the changes
                    mytravelentities.SaveChanges()
                Catch opt As OptimisticConcurrencyException
                    ' catching this exception allows you to 
                    ' refresh MyTravelPostEntities with either store/client wins
                    ' project the MyTravelPostEntities into this failed MyTravelPostEntities.
                    Dim failedEntities = From e3 In opt.StateEntries Select e3.Entity

                    ' Note: in future you should be able to just pass the opt.StateEntities in to refresh.
                    mytravelentities.Refresh(RefreshMode.ClientWins, failedEntities.ToList())
                    mytravelentities.SaveChanges()
                End Try

            End Using
        Catch ex As Exception
            ' NOTE: You should do your own exception handling here
            ' problems may be connection, metadata, or there problems.
            Throw ex
        End Try

        Return orginalComments
    End Function

    ' see IMyTravelPostService for details
    Public Sub ChangeBlogowner(ByVal blog As Blog, ByVal newBlogOwnerKey As EntityKey) Implements IMyTravelPostService.ChangeBlogowner
        Try
            ' the creation of the travelEntities opens the connection 
            ' and sets up all the metadata information automatically for you.
            Using mytravelentities As New MyTravelEntities
                ' attach the blog,
                mytravelentities.Attach(blog)

                ' by having the EntityKey on the PersonReference
                ' you can change the relationship to a new blog owner
                ' via the entity key. The new EntityKey must exists in the database
                blog.PersonReference.EntityKey = newBlogOwnerKey

                Try
                    ' save the changes
                    mytravelentities.SaveChanges()
                Catch opt As OptimisticConcurrencyException
                    ' catching this exception allows you to 
                    ' refresh MyTravelPostEntities with either store/client wins
                    ' project the MyTravelPostEntities into this failed MyTravelPostEntities.
                    Dim failedEntities = From e3 In opt.StateEntries Select e3.Entity

                    ' Note: in future you should be able to just pass the opt.StateEntities in to refresh.
                    mytravelentities.Refresh(RefreshMode.ClientWins, failedEntities.ToList())
                    mytravelentities.SaveChanges()
                End Try

            End Using
        Catch ex As Exception
            ' NOTE: You should do your own exception handling here
            ' problems may be connection, metadata, or there problems.
            Throw ex
        End Try

    End Sub
End Class
